// 全局命名空间
var K = this.K || {};

// 资源加载
K.Resource = K.Resource || {};

K.error = function(obj, type) {
	type = type || Error;
	throw new type(obj);
};

K.global = this;

// 工具函数
(function(K) {

var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;

var slice			= ArrayProto.slice,
    unshift		  = ArrayProto.unshift,
    toString		 = ObjProto.toString,
    hasOwnProperty   = ObjProto.hasOwnProperty;

// ECMAScript 5 原生方法
var
	nativeForEach	  = ArrayProto.forEach,
	nativeMap		  = ArrayProto.map,
	nativeReduce	   = ArrayProto.reduce,
	nativeReduceRight  = ArrayProto.reduceRight,
	nativeFilter	   = ArrayProto.filter,
	nativeEvery		= ArrayProto.every,
	nativeSome		 = ArrayProto.some,
	nativeIndexOf	  = ArrayProto.indexOf,
	nativeLastIndexOf  = ArrayProto.lastIndexOf,
	nativeIsArray	  = Array.isArray,
	nativeKeys		 = Object.keys,
	nativeCreate     = Object.create,
	nativeBind		 = FuncProto.bind;

// 调试信息
K.log = function() {
	if (! K.__debug) {
		return;
	}
	if ('console' in window && 'log' in window.console) {
		var len = arguments.length;
		if (len == 1) {
			window.console.log(arguments[0]);
		} else if (len == 2) {
			window.console.log(arguments[0], arguments[1]);
		}
	} else if (window.opera && window.opera.postError) {
		window.opera.postError.apply(window.opera, arguments);
	}
};

// 集合操作函数
// -----------------

var breaker = {};

// 遍历集合
K.forEach = function(obj, iterator, context) {
	if (obj == null) {
		return;
	}
	if (nativeForEach && obj.forEach === nativeForEach) {
		obj.forEach(iterator, context);
	} else if (K.isNumber(obj.length)) {
		for (var i = 0, l = obj.length; i < l; i++) {
			if (iterator.call(context, obj[i], i, obj) == breaker) {
				return;
			}
	  	}
	} else {
		for (var key in obj) {
			if (hasOwnProperty.call(obj, key)) {
		  		if (iterator.call(context, obj[key], key, obj) === breaker) {
					return;
				}
			}
	  	}
	}
};

// 在对象中的每个属性项上运行一个函数，并将函数返回值作为属性的值。
K.map = function(obj, iterator, context) {
	var results = [];
	if (obj == null) {
		return results;
	}
	if (nativeMap && obj.map === nativeMap) {
		return obj.map(iterator, context);
	}
	K.forEach(obj, function(value, index, list) {
	  results[results.length] = iterator.call(context, value, index, list);
	});
	return results;
};

// 对集合元素进行递推操作
K.reduce = function(obj, iterator, memo, context) {
	var initial = memo !== void 0;
	if (obj == null) {
		obj = [];
	}
	if (nativeReduce && obj.reduce === nativeReduce) {
		if (context) {
			iterator = K.bind(iterator, context);
		}
		return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
	}
	K.forEach(obj, function(value, index, list) {
		if (!initial && index === 0) {
			memo = value;
			initial = true;
	  	} else {
			memo = iterator.call(context, memo, value, index, list);
	  	}
	});
	if (!initial) {
		throw new TypeError("Reduce of empty array with no initial value");
	}
	return memo;
};

// 为集合元素进行逆向递推操作。
K.reduceRight = function(obj, iterator, memo, context) {
	if (obj == null) {
		obj = [];
	}
	if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
		if (context) iterator = K.bind(iterator, context);
	  	return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
	}
	var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
	return _.reduce(reversed, iterator, memo, context);
};

// 在集合中查找符合条件的第一个元素
K.detect = function(obj, iterator, context) {
	var result;
	K.some(obj, function(value, index, list) {
		if (iterator.call(context, value, index, list)) {
			result = value;
			return true;
	  	}
	});
	return result;
};

// 在集合每一个元素上运行一个函数，将函数返回值为真的元素作为数组返回
K.filter = function(obj, iterator, context) {
	var results = [];
	if (obj == null) {
		return results;
	}
	if (nativeFilter && obj.filter === nativeFilter) {
		return obj.filter(iterator, context);
	}
	K.forEach(obj, function(value, index, list) {
		if (iterator.call(context, value, index, list)) results[results.length] = value;
	});
	return results;
};

// 判断是否集合中所有元素都为真
K.every = function(obj, iterator, context) {
	var result = true;
	if (obj == null) {
		return result;
	}
	if (nativeEvery && obj.every === nativeEvery) {
		return obj.every(iterator, context);
	}
	K.forEach(obj, function(value, index, list) {
	  if (!(result = result && iterator.call(context, value, index, list))) {
		  return breaker;
	  }
	});
	return result;
};

// 判断集合中是否有元素符合条件
K.some = function(obj, iterator, context) {
	iterator || (iterator = K.identity);
	var result = false;
	if (obj == null) {
		return result;
	}
	if (nativeSome && obj.some === nativeSome) {
		return obj.some(iterator, context);
	}
	K.forEach(obj, function(value, index, list) {
		if (iterator.call(context, value, index, list)) {
			result = true;
			return breaker;
		}
	});
	return result;
};

// 判断集合中是否包含某元素
K.contains = function(obj, target) {
	var found = false;
	if (obj == null) {
		return found;
	}
	if (nativeIndexOf && obj.indexOf === nativeIndexOf) {
		return obj.indexOf(target) != -1;
	}
	K.some(obj, function(value) {
	  if (found = value === target) {
		  return true;
	  }
	});
	return found;
};

// 返回包含集合中所有元素的key属性的数组
K.pluck = function(obj, key) {
	return K.map(obj, function(value) {
		return value[key];
	});
};

// 对集合元素进行排序
K.sortBy = function(obj, iterator, context) {
	return K.pluck(K.map(obj, function(value, index, list) {
		return {
			value : value,
			criteria : iterator.call(context, value, index, list)
	  	};
	}).sort(function(left, right) {
		var a = left.criteria, b = right.criteria;
		return a < b ? -1 : a > b ? 1 : 0;
	}), 'value');
};

// Use a comparator function to figure out at what index an object should
// be inserted so as to maintain order. Uses binary search.
K.sortedIndex = function(array, obj, iterator) {
	iterator || (iterator = K.identity);
	var low = 0, high = array.length;
	while (low < high) {
	  	var mid = (low + high) >> 1;
	  	iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
	}
	return low;
};

// 转化成数组
K.toArray = function(iterable) {
	if (!iterable)				return [];
	if (iterable.toArray)		 return iterable.toArray();
	if (K.isArray(iterable))	  return iterable;
	if (K.isArguments(iterable))  return slice.call(iterable);
	return K.values(iterable);
};

// 数组操作
// ---------------

// 获取数组最后一个元素
K.last = function(array) {
	var len = array.length;
	return len > 0 ? array[ len - 1 ] : undefined;
};

// 获取数组中真值的项。
K.compact = function(array) {
	return K.filter(array, function(value) {
		return !!value;
	});
};

// 将一个数组扁平化
K.flatten = function(array) {
	return K.reduce(array, function(memo, value) {
		if (K.isArray(value)) {
			return memo.concat(K.flatten(value));
	  	}
	  	memo[memo.length] = value;
	  	return memo;
	}, []);
};

// 将数组里的某(些)元素移除。
K.without = function(array, obj) {
	var values = slice.call(arguments, 1);
	return K.filter(array, function(value) {
		return !K.contains(values, value);
	});
};

// 数组元素除重，得到新数据
K.unique = function(array, isSorted) {
	return K.reduce(array, function(memo, el, i) {
		if (0 == i || (isSorted === true ? K.last(memo) != el : !K.contains(memo, el))) memo[memo.length] = el;
	  	return memo;
	}, []);
};

// 获取多个数组的交集
K.intersect = function(array) {
	var rest = slice.call(arguments, 1);
	return K.filter(K.unique(array), function(item) {
		return K.every(rest, function(other) {
			return K.indexOf(other, item) >= 0;
		});
	});
};

// 返回一个元素在数组中的位置（从前往后找）。如果数组里没有该元素，则返回-1
K.indexOf = function(array, item, isSorted) {
	if (array == null) return -1;
	var i, l;
	if (isSorted) {
		i = K.sortedIndex(array, item);
	  	return array[i] === item ? i : -1;
	}
	if (nativeIndexOf && array.indexOf === nativeIndexOf) {
		return array.indexOf(item);
	}
	for (i = 0, l = array.length; i < l; i++) if (array[i] === item) {
		return i;
	}
	return -1;
};

// 返回一个元素在数组中的位置（从后往前找）。如果数组里没有该元素，则返回-1
K.lastIndexOf = function(array, item) {
	if (array == null) return -1;
	if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
		return array.lastIndexOf(item);
	}
	var i = array.length;
	while (i--) if (array[i] === item) {
		return i;
	}
	return -1;
};

// 函数操作
// ------------------

// 绑定
K.bind = function(func, context) {
	var extraArgs = Array.prototype.slice.call(arguments, 2);
	return function() {
		context = context || (this == K.global ? false : this);
		var args = extraArgs.concat(Array.prototype.slice.call(arguments));
		if (typeof(func) == "string" && context[func]) {
			context[func].apply(context, args);
		} else if (K.isFunction(func)) {
			return func.apply(context, args);
		} else {
			K.log("not function", func);
		}
	};
};


// 对函数进行methodize化，使其的第一个参数为this，或this[attr]。
K.methodize = function(func, attr) {
	if (attr) {
		return function() {
			return func.apply(null, [this[attr]].concat([].slice.call(arguments)));
		};
	}
	return function() {
		return func.apply(null, [this].concat([].slice.call(arguments)));
	};
};

K.extend = function(klass, proto) {
	var T = function() {}; //构造prototype-chain
	T.prototype = proto.prototype;

	var klassProto = klass.prototype;

	klass.prototype = new T();
	klass.$super = proto; //在构造器内可以通过arguments.callee.$super执行父类构造

	//如果原始类型的prototype上有方法，先copy
	K.mix(klass.prototype, klassProto, true);

	return klass;
};

// 以某对象为原型创建一个新的对象
K.create = nativeCreate || function(proto, props) {
	var ctor = function(ps) {
		if (ps) {
			K.mix(this, ps, true);
		}
	};
	ctor.prototype = proto;
	return new ctor(props);
};

// 延迟执行函数
K.delay = function(func, wait) {
	var args = slice.call(arguments, 2);
	return setTimeout(function() {
		return func.apply(func, args);
	}, wait);
};

K.defer = function(func) {
	return K.delay.apply(K, [func, 1].concat(slice.call(arguments, 1)));
};

// 对象操作
// ----------------

// 得到一个对象中所有可以被枚举出的属性的列表
K.keys = nativeKeys || function(obj) {
	if (obj !== Object(obj)) {
		throw new TypeError('Invalid object');
	}
	var keys = [];
	for (var key in obj) if (hasOwnProperty.call(obj, key)) {
		keys[keys.length] = key;
	}
	return keys;
};

// 得到一个对象中所有可以被枚举出的属性值的列表
K.values = function(obj) {
	return K.map(obj, K.identity);
};

// 得到一个对象中所有可以被枚举出的方法列表
K.methods = function(obj) {
	return K.filter(K.keys(obj), function(key) {
		return _.isFunction(obj[key]);
	}).sort();
};

// 将源对象的属性并入到目标对象
K.mix = function(obj) {
	K.forEach(slice.call(arguments, 1), function(source) {
		for (var prop in source) if (source[prop] !== void 0) {
			obj[prop] = source[prop];
	  	}
	});
	return obj;
};

// 克隆
K.clone = function(obj) {
	return K.isArray(obj) ? obj.slice() : K.mix({}, obj);
};

// 是否为空数组或对象
K.isEmpty = function(obj) {
	if (K.isArray(obj) || K.isString(obj)) {
		return obj.length === 0;
	}
	for (var key in obj) if (hasOwnProperty.call(obj, key)) {
		return false;
	}
	return true;
};

// 判断一个变量是否是Html的Element元素
K.isElement = function(obj) {
	return !!(obj && obj.nodeType == 1);
};

// 判断对象是否为数组
K.isArray = nativeIsArray || function(obj) {
	return toString.call(obj) === '[object Array]';
};

// 判断对象是否为函数
K.isFunction = function(obj) {
	return !!(obj && obj.constructor && obj.call && obj.apply);
};

if (toString.call(arguments) == '[object Arguments]') {
    K.isArguments = function(obj) {
        return toString.call(obj) == '[object Arguments]';
    };
} else {
    K.isArguments = function(obj) {
        return !!(obj && hasOwnProperty.call(obj, 'callee'));
    };
}


// 判断对象是否为字符串
K.isString = function(obj) {
	return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
};

// 判断对象是否为数字
K.isNumber = function(obj) {
	return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
};

// 判断对象是否是Nan
K.isNaN = function(obj) {
	return obj !== obj;
};

// 判断对象是否为boolean类型
K.isBoolean = function(obj) {
	return obj === true || obj === false;
};

// 判断对象是否为Date类型
K.isDate = function(obj) {
	return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
};

// 判断对象是否为正则
K.isRegExp = function(obj) {
	return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
};

// 判断对象是否为null
K.isNull = function(obj) {
	return obj === null;
};

// 判断对象是否为undefined
K.isUndefined = function(obj) {
	return obj === void 0;
};

// 字符函数
// -----------------

// 除去字符串两边的空白字符
K.trim = function(str) {
	return str.replace(/^[\s\xa0\u3000]+|[\u3000\xa0\s]+$/g, "");
};

// 得到字节长度
K.byteLen = function(str) {
	return str.replace(/[^\x00-\xff]/g, "--").length;
};

// 得到指定字节长度的子字符串
K.subByte = function(str, len, tail) {
	if (K.byteLen(str) < len) {
		return str;
	}
	tail = tail || '';
	len -= K.byteLen(tail);
	return str.substr(0, len).replace(/([^\x00-\xff])/g, "$1 ") //双字节字符替换成两个
			  .substr(0, len) // 截取长度
			  .replace(/[^\x00-\xff]$/, "") //去掉临界双字节字符
			  .replace(/([^\x00-\xff]) /g, "$1") + tail; //还原
};

// 字符串为javascript转码
K.encode4JS = function(str) {
	return str.replace(/\\/g, "\\u005C")
			  .replace(/"/g, "\\u0022")
			  .replace(/'/g, "\\u0027")
			  .replace(/\//g, "\\u002F")
			  .replace(/\r/g, "\\u000A")
			  .replace(/\n/g, "\\u000D")
			  .replace(/\t/g, "\\u0009");
};

// 为http的不可见字符、不安全字符、保留字符作转码
K.encode4HTTP = function(str) {
	return str.replace(/[\u0000-\u0020\u0080-\u00ff\s"'#\/\|\\%<>\[\]\{\}\^~;\?\:@=&]/, function(s) {
		return encodeURIComponent(s);
	});
};

/**
* 字符串为Html转码
* @method encode4Html
* @static
* @param {String} s 字符串
* @return {String} 返回处理后的字符串
* @example
	var s="<div>dd";
	alert(encode4Html(s));
*/
K.encode4Html = function(s){
	return s.replace(/&(?!\w+;|#\d+;|#x[\da-f]+;)/gi, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
};

/**
* 字符串为Html的value值转码
* @method encode4HtmlValue
* @static
* @param {String} s 字符串
* @return {String} 返回处理后的字符串
* @example:
	var s="<div>\"\'ddd";
	alert("<input value='"+encode4HtmlValue(s)+"'>");
*/
K.encode4HtmlValue = function(s){
	return K.encode4Html(s).replace(/"/g,"&quot;").replace(/'/g,"&#039;");
}

// 将所有tag标签消除，即去除<tag>，以及</tag>
K.stripTags = function(str) {
	return str.replace(/<[^>]*>/gi, '');
};

//日期函数
//------------------
/**
* 格式化日期
* @method format
* @static
* @param {Date} d 日期对象
* @param {string} pattern 日期格式(y年M月d天h时m分s秒)，默认为"yyyy-MM-dd"
* @return {string}  返回format后的字符串
* @example
	var d=new Date();
	alert(format(d," yyyy年M月d日\n yyyy-MM-dd\n MM-dd-yy\n yyyy-MM-dd hh:mm:ss"));
*/
K.formatDate = function(d,pattern){
	pattern=pattern||"yyyy-MM-dd";
	var y=d.getFullYear();
	var o = {
		"M" : d.getMonth()+1, //month
		"d" : d.getDate(),    //day
		"h" : d.getHours(),   //hour
		"m" : d.getMinutes(), //minute
		"s" : d.getSeconds() //second
	}
	pattern=pattern.replace(/(y+)/ig,function(a,b){var len=Math.min(4,b.length);return (y+"").substr(4-len);});
	for(var i in o){
		pattern=pattern.replace(new RegExp("("+i+"+)","g"),function(a,b){return (o[i]<10 && b.length>1 )? "0"+o[i] : o[i]});
	}
	return pattern;
}

// 工具函数
// -----------------

K.identity = function(value) {
	return value;
};

// 生成唯一ID
var idCounter = 0;
K.uniqueId = function(prefix) {
	var id = idCounter++;
	return prefix ? prefix + id : id;
};

})(K);

// touch事件检测
( function(K, undefined) {
	var result;

	var detect = function() {
		K.log('detecting touch support');
		var events = ['touchstart', 'touchmove', 'touchend'],
		    flag = true;

		var el = document.createElement('div');

		for (var i=0, j=events.length; i<j; i++) {
			var eventName = 'on' + events[i];
			var isSupported = (eventName in el);
			if (! isSupported) {
				el.setAttribute(eventName, 'return;');
				isSupported = typeof el[eventName] == 'function';
			}
			if (! isSupported) {
				flag = false;
				break;
			}
		}
		return flag;
	};

	K.isSupportTouch = function() {
		if (result === undefined) {
			result = detect();
		}
		return result;
	};
})( K );

// js的运行环境，浏览器以及版本信息。（Browser仅基于userAgent进行嗅探，存在不严谨的缺陷。）
K.Browser = (function() {
	var na = window.navigator,
		ua = na.userAgent.toLowerCase(),
		browserTester = /(msie|webkit|gecko|presto|opera|safari|firefox|chrome|maxthon)[ \/]([\d.]+)/ig,
		Browser = {
			platform: na.platform
		};
	ua.replace(browserTester, function(a, b, c) {
		var bLower = b.toLowerCase();
		Browser[bLower] = c;
	});
	if (Browser.opera) { //Opera9.8后版本号位置变化
		ua.replace(/opera.*version\/([\d.]+)/, function(a, b) {
			Browser.opera = b;
		});
	}
	if (Browser.msie) {
		Browser.ie = Browser.msie;
		var v = parseInt(Browser.msie, 10);
		Browser['ie' + v] = true;
	}

	if( Browser.safari && Browser.chrome ){
		Browser.safari = false;
	}
	return Browser;
}());

if (K.Browser.ie) {
	try {
		document.execCommand("BackgroundImageCache", false, true);
	} catch (e) {}
}

//鉴于该脚本加载时间比较靠前，故将窗口是否Focus的判断放在此处，提高准确性
function onDetectFocus(){
	K.windowFocused = true;
}
function onDetectBlur(){
	K.windowFocused = false;
}


if( K.Browser.ie ){
	document.attachEvent( 'onfocusin', onDetectFocus);
	document.attachEvent( 'onfocusout', onDetectBlur);
}
else{
	window.addEventListener( 'focus', onDetectFocus, false );
	window.addEventListener( 'blur', onDetectBlur, false );
}

// 内部使用的 Event
( function( K ) {

var Pubsub = function() {
	this.__callbacks__ = {};
};

K.mix( Pubsub.prototype, {
	on: function(name, callback, context) {
		if (context) {
			callback = K.bind(callback, context);
		}

		var arr = this.__callbacks__[name];
		if( arr && arr.fired === true ){
			callback.apply( context, arr.args );
			return;
		}

		//如果是fireReady并且已经触发则立即执行回调

		this.__callbacks__[name] = this.__callbacks__[name] || [];
		this.__callbacks__[name].push(callback);

		return [ name, callback ];
	},

	un: function( handle ) {
		var name = handle[0];
		var callback = handle[1];

		if ( name in this.__callbacks__ ) {
			var callbacks = this.__callbacks__[name];
			K.forEach( callbacks, function(cb, i) {
				if (callback == cb) {
					callbacks[i] = null;
				}
			} );
		}
	},

	once: function(name, callback, context) {
		var me = this;
		var handle = this.on( name, function() {
			callback.apply( context, arguments );
			me.un( handle );
		} );
	},

	fire: function(name/* args */) {
		if ( name in this.__callbacks__ ) {
			var callbacks = this.__callbacks__[name];
			var args = Array.prototype.slice.call(arguments, 1);
			K.forEach( callbacks, function(callback, i) {
				if ( typeof(callback) != "function" ) {
					return null;
				}
				return callback.apply(null, args);
			} );
		}
	},
	/**
	 * fireReady触发的事件的特点是，即使是事件已经触发，后续on注册的callback仍然会执行
	 * 同时请注意，这类事件应该只触发一次，多次会导致逻辑混乱
	 */
	fireReady: function(name/* args */){
		var callbacks = this.__callbacks__[name];
		if( !callbacks ){
			callbacks = this.__callbacks__[name] = [];
		}
		var args = Array.prototype.slice.call(arguments, 1);
		K.forEach( callbacks, function(callback, i) {
			if ( typeof(callback) != "function" ) {
				return null;
			}
			return callback.apply(null, args);
		});
		callbacks.fired = true;
		callbacks.args = args;
	}
} );

K.Pubsub = Pubsub;
K.mix( K, ( new Pubsub() ) );

} )( K );

// Module
( function( K, Resource, global ) {

var definedModules = {}; // 已定义过的模块
var loadingModules = {}; // 加载中模块

function Module ( id, dependancy, factory ) {
	// 模块不能依赖自身
	if ( K.indexOf( dependancy, id ) >= 0 ) {
		throw new Error( 'Module:' + id + ' could\'t depends on itself!' );
	}

	this.id = id;
	this.dependancy = dependancy;
	this.factory = factory;
};


/**************************************
 * define( moduleId, dependancy, factory )
 * @param {string} moduleId
 * @param {array} dependancy
 * @param {function} factory
 **************************************/
function define( moduleId, dependancy, factory ) {
	if ( arguments.length < 2 ) {
		throw new Error( 'module has invalid parameters' );
	}

	if ( ! K.isString( moduleId ) ) {
		throw new Error( 'module must have a ID' );
	}

	// define( 'xx', function() {} );
	if ( K.isFunction( dependancy ) ) {
		factory = dependancy;
		dependancy = [];
	}
	// define( 'xxx', {} );
	else if ( !K.isArray( dependancy ) ) {
		var def = dependancy; // 不能省略这个赋值，因为dependancy在后面被改写了。
		factory = function(){ return def; };
		dependancy = [];
	}

	if ( definedModules[ moduleId ] ) {
        K.fire('haibei:resource:conflict');
        // 不抛异常
		// throw new Error( moduleId + ' has defined' );
		return;
	}

	var realDependancy = K.unique( dependancy ),
		allModules = Module.getDependancy( realDependancy );

	Module.wait( allModules, function() {
		var mod = new Module( moduleId, dependancy, factory );
		definedModules[ moduleId ] = mod;

		try {
			delete loadingModules[ moduleId ];
		} catch(e) {}

		K.fire( 'Module:' + moduleId + ':Ready' );
	} );
}

Module.createRequire = function( depends, sourceId ) {
	function require( id, async ) {
		if ( !async && K.indexOf( depends, id ) == -1 ) {
			throw new Error( id + ' counld\'t be required in ' + sourceId + ', as you not declared to depend it ' );
		}

		var mod = definedModules[ id ];

		if ( !mod ) {
			return null;
		}

		if ( !mod.exports ) {
			createExports( mod );
		}

		return mod.exports;
	}

	require.async = function( modules, callback, context ) {
		modules = K.isString( modules ) ? [ modules ] : modules;
		var realModules = K.unique( modules );
		var allModules = Module.getDependancy( realModules );

		Module.load( allModules );
		Module.wait( allModules, function() {
			var mods = [];
			for ( var i = 0, length = modules.length; i < length; i++ ) {
				mods.push( require( modules[ i ], true ) );
			}

			callback.apply( context || global, mods );
		} );

	};

	return require;
};

/**
 * 获得模块依赖列表
 * @param {array} 依赖模块ID列表
 * @return {array} 模块ID列表
 */
Module.getDependancy = function( midList ) {
	return Resource.getDependancy( midList );
};

/**
 * 加载模块
 * 只是简单的将script中添加到dom树中
 * 不检测文件是否加载完成
 */
Module.load = function( moduleList ) {
	moduleList = K.isString( moduleList ) ? [ moduleList ] : moduleList;

	K.forEach( moduleList, function( mid ) {
		Resource.loadModule( mid );
	} );
};

/**
 * 检测所有已加载完成的模块
 */
Module.defined = function() {
	return definedModules;
};

/**
 * 检测加载中模块
 */
Module.waiting = function() {
	return K.keys( loadingModules );
};

/**
 * 检测模块是否加载完毕
 * 如果没有则等待
 */
Module.check = function( mid, callback ) {
	mid = K.trim( mid );
	if ( mid.length == 0 || definedModules[ mid ] ) {
		callback && callback();

	} else {
		// 记录正在加载中的模块
		loadingModules[ mid ] = true;
		K.on( 'Module:' + mid + ':Ready', callback );
	}
};

/**
 * 等待所有的依赖模块加载完毕
 * 串行检测所依赖模块
 * @param { array } dependancy 依赖模块
 * @param { function } callback 回调函数
 */
Module.wait = function( dependancy, callback ) {
	dependancy = [].concat( dependancy );
	if ( dependancy.length > 0 ) {
		var mod = dependancy.shift();
		Module.check( mod, function() {
			Module.wait( dependancy, callback );
		} );
	} else {
		callback && callback();
	}
};

function createExports( mod ) {
	var factory = mod.factory,
		ret;

	if ( K.isFunction( factory ) ) {
		mod.exports = {};
		ret = factory( Module.createRequire( mod.dependancy, mod.id ), mod.exports, mod );
		if ( ret ) {
			mod.exports = ret;
		}
	}
	else if ( factory !== undefined ) {
		mod.exports = factory;
	}
}

// 暴露api
global.define = K.define = define;
global.Module = K.Module = Module;

} )( K, K.Resource, this );


( function( K, Resource ) {

var resourceMap = {};		// 静态文件版本信息
var dependsMap = {};		// 静态文件依赖信息
var resourceBasePath = 'http://{_STCHOST_}/';	// 静态文件base地址
var rjs = /\.js$/i;
var _loaded = {};           // 已经加载的静态文件
var _loading = {};			// 正在加载中的静态文件
var _callbacks = [];		// 静态文件加载的回调列表
var _links = [];			// 加载中的css列表
var _timer ; 				// 轮询css加载状态的定时器


/**
 * 添加静态文件版本信息
 * @param {object} map
 */
Resource.addResourceMap = function( map ) {
	K.mix( resourceMap, map );
};


/**
 * 获得静态文件版本信息
 */
Resource.getResourceMap = function( file ) {
    return resourceMap[file];
};


/**
 * 添加静态文件依赖信息
 * @param {object} map
 */
Resource.addResourceDepends = function( map ) {
	K.mix( dependsMap, map );
};

/**
 * 开发时用
 */
Resource.setBasePath = function( path ) {
	resourceBasePath = path;
};


/**
 * 获取依赖模块
 * @param {array|string} 依赖模块列表
 * @param {array} inlist 已经找出的依赖模块
 * todo 处理循环依赖
 */
Resource.getDependancy = function( midList, inlist ) {
	var ret = [];

	midList = K.isString( midList ) ? [ midList ] : midList;
	inlist = inlist || [];

	K.forEach( midList, function( mid ) {
		mid = mid.replace( rjs, '' );
		inlist = inlist.concat( ret );
		if ( K.indexOf( inlist, mid ) == -1 ) {
			ret.unshift( mid );
		}

		var depends = dependsMap[ mid + '.js' ];
		if ( !depends ) {
			return;
		}

		var more = Resource.getDependancy( depends, inlist );
		if ( more.length ) {
			ret.unshift.apply( ret, more );
		}
	} );

	return ret;
};

/**
 * 加载模块
 */
var rslash = /^\/+|\/+$/ig;
Resource.loadModule = function( mid ) {
	mid = mid.replace( rslash, '' );

	if ( !rjs.test( mid ) ) {
		mid += '.js';
	}

	var uri = resourceMap[ mid ];
	if ( uri ) {
		Resource.loadJS( resourceBasePath + uri );
	}
};

Resource.canonicalURI = function(src) {
	if (/^\/\/\/?/.test(src)) {
		src = location.protocol + src;
	}
	return src;
};

var _initResourceMap = function() {
	var allTags = document.getElementsByTagName('link'),
		len = allTags.length,
		tag;
	while (len) {
		tag = allTags[--len];
		if ((tag.rel == 'stylesheet' || tag.type == 'text/css') && tag.href) {
			_loaded[Resource.canonicalURI(tag.href)] = true;
		}
	}

	allTags = document.getElementsByTagName('script');
	len = allTags.length;
	while (len) {
		tag = allTags[--len];
		if ((!tag.type || tag.type == "text/javascript") && tag.src) {
			_loaded[Resource.canonicalURI(tag.src)] = true;
		}
	}

	_initResourceMap = function() {};
};

var _complete = function(uri) {
	var list = _callbacks,
		item, i;

	delete _loading[uri];
	_loaded[uri] = true;

	for (i=0; i<list.length; i++) {
		item = list[i];
		delete item.resources[uri];
		if (K.isEmpty(item.resources)) {
			item.callback && item.callback();
			list.splice(i--, 1);
		}
	}
};

var _poll = function() {
	var sheets = document.styleSheets,
		i = sheets.length,
		links = _links;

	while (i--) {
		var link = sheets[i],
			ready = false;

		if (! K.Browser.firefox) {
			ready = true;
		} else {
			try {
				if (link.cssRules) {
					ready = true;
				}
			} catch (ex) {
				if (ex.code == 1000) {
					ready = true;
				}
			}
		}

		if (ready) {
			var owner = link.ownerNode || link.owningElement,
			j = links.length;

			if (owner) {
				while (j--) {
					if (owner == links[j]) {
						_complete(links[j]['data-href']);
						links.splice(j, 1);
					}
				}
			}
		}
	}

	if (! links.length) {
		clearInterval(_timer);
		_timer = null;
	}
};

var _injectJS = function(uri) {
	var script = document.createElement('script');
	var callback = function() {
		script.onload = script.onerror = script.onreadystatechange = null;
		_complete(uri);
	};

	K.mix(script, {
		type: 'text/javascript',
		src: uri
	});
	script.onload = script.onerror = callback;
	script.onreadystatechange = function() {
		var state = this.readyState;
		if (state == 'complete' || state == 'loaded') {
			callback();
		}
	};
	document.getElementsByTagName('head')[0].appendChild(script);
};

var _injectCSS = function( uri ) {
	var link = document.createElement('link');
	K.mix(link, {
		type: 'text/css',
		rel: 'stylesheet',
		href: uri,
		'data-href': uri
	});
	document.getElementsByTagName('head')[0].appendChild(link);

	if (link.attachEvent) {
		var callback = function() {
			_complete(uri);
		};
		link.onload = callback;
	} else {
		_links.push(link);
		if (! _timer) {
			_timer = setInterval(_poll, 20);
		}
	}
};

var _load = function(list, callback) {
	var resources = {},
		uri, path, type, ret;

	_initResourceMap();

	list = K.isArray(list) ? list : [ list ];
	for (var i=0, j=list.length; i < j; i++) {
		uri = Resource.canonicalURI(list[i]);
		resources[uri] = true;

		if (_loaded[uri]) {
			setTimeout(K.bind(_complete, null, uri), 0);
		} else if (! _loading[uri]) {
			_loading[uri] = true;
			if (uri.indexOf('.css') > -1) {
				_injectCSS(uri);
			} else {
				_injectJS(uri);
			}
		}
	}

	if (callback) {
		_callbacks.push({
			resources: resources,
			callback: callback
		});
	}
};

/**
 * 加载JS文件
 * @param {mixed} src JS文件绝对地址
 * @param {function} callback js加载完成后回调函数
 */
Resource.loadJS = function( src, callback ) {
	_load(src, callback);
};


/**
 * 加载CSS文件
 * @param {mixed} uri css文件绝对地址
 * @param {function} callback todo: 文件加载完成后回调函数
 */
Resource.loadCSS = function( uri, callback ) {
	_load(uri, callback);
};

/**
 * 加载image文件
 * @param {string} uri image文件绝对地址
 * @param {function} callback todo: 文件加载完成后回调函数
 */
Resource.loadIMG = function( src, callback ) {
    var image = new Image();

    callback = typeof callback === 'function' ? callback : function() {};
    image.onload = function() {
        image.onload = null;
        callback.call( null, image );
    };
    if ( image.readyState == "complete" ) {
        callback.call(null, image);
    }
    image.src = src;
};


} )( K, K.Resource );


// Dom Ready
( function(K) {

var isDomContentLoaded = false;
var isWindowLoaded = false;

K.ready = function(callback) {
	if ( isDomContentLoaded ) {
		callback();
	} else {
		K.on( 'Onload:DomContentLoaded', callback );
	}
};

K.load = function(callback) {
    if ( isWindowLoaded ) {
        callback();
    } else {
        K.on( 'Onload:Loaded', callback );
    }
};

var onDomContentLoaded = function() {
	if ( ! isDomContentLoaded ) {
		isDomContentLoaded = true;
		K.fire( "Onload:DomContentLoaded" );
	}
};

var onWindowLoaded = function() {
	if ( ! isWindowLoaded ) {
		isWindowLoaded = true;
		K.fire( "Onload:Loaded" );
	}
};

var DOMContentLoaded;
if ( document.addEventListener ) {
	DOMContentLoaded = function() {
		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
		onDomContentLoaded();
	};
} else if ( document.attachEvent ) {
	DOMContentLoaded = function() {
		if ( document.readyState === "complete" ) {
			document.detachEvent( "onreadystatechange", DOMContentLoaded );
			onDomContentLoaded();
		}
	};
}

var doScrollCheck = function() {
	if ( isDomContentLoaded ) {
		return;
	}

	try {
		// If IE is used, use the trick by Diego Perini
		// http://javascript.nwbox.com/IEContentLoaded/
		document.documentElement.doScroll( "left" );
	} catch(e) {
		setTimeout( doScrollCheck, 1 );
		return;
	}

	// and execute any waiting functions
	document.detachEvent( "onreadystatechange", DOMContentLoaded );
	onDomContentLoaded();
};

var bootstrapHandler = function() {

	var window = K.global,
	    document = window.document,
		onloadHandler = function() {
			if ( ! isDomContentLoaded ) {
				isDomContentLoaded = true;
				onDomContentLoaded();
			}

			onWindowLoaded();
		};

	if ( document.readyState == "complete" ) {
		setTimeout( onDomContentLoaded, 0 );
		return;
	}

	if ( document.addEventListener ) {
		document.addEventListener('DOMContentLoaded', DOMContentLoaded, false);
		window.addEventListener( 'load', onloadHandler, false );
	} else if ( document.attachEvent ) {
		document.attachEvent( "onreadystatechange", DOMContentLoaded );
		window.attachEvent( "onload", onloadHandler );

		// If IE and not a frame
		// continually check to see if the document is ready
		var toplevel = false;

		try {
			toplevel = window.frameElement == null;
		} catch(e) {}

		if ( document.documentElement.doScroll && toplevel ) {
			doScrollCheck();
		}
	}
};

bootstrapHandler();

} )( K );


// APP
( function( K, Module ) {

var reserveMethods = 'require getContainer'.split( /\s+/ig );  // 一些保留属性或者方法
var appList = {};

function Application( id, dependancy, execBeforeDomready ) {
	if ( appList[ id ] ) {
        K.fire('haibei:resource:conflict');
		throw new Error( 'App:' + id + ' has defined' );
        return;
	}
	appList[ id ] = this;
	this.id = id;

	// App默认加载jQuery
	this.requiredModList = [ 'jQuery' ].concat( dependancy );
	this.execBeforeDomready = execBeforeDomready;
}

K.mix( Application.prototype, {
	'define' : function( definition ) {
		var dependancy = K.unique( this.requiredModList ),
			allModules = Module.getDependancy( dependancy ),
			me = this,
			ready = function() {
				K.fire( 'App:' + me.id + ':Ready', me );
			};

		//alert( allModules );
		// 加载所有模块
		//Module.load( allModules );

		// 等待加载完成
		Module.wait( allModules, function() {
			// factory 方法
			// 如果是以factory方式，会定义两个不同的require
			// 防止factory里通过 this.require = xxx 方式覆盖
			// 如果factory里覆盖了require方法，暂时无法检测
			var require = Module.createRequire( dependancy, me.id );
			if ( K.isFunction( definition ) ) {
				definition = definition.call( {
					'require' : Module.createRequire( dependancy, me.id )
				}, require );
			}

			// App的factory可能没有return definition
			if ( !definition ) {
				return;
			}

			// 检测definition中是否定义了保留方法
			var i, length, prop;
			for ( i = 0, length = reserveMethods.length; i < length; i++ ) {
				prop = reserveMethods[ i ];
				if ( definition[ prop ] ) {
					throw new Error( prop + ' is a reserve method or property' );
				}
			}

			definition.require = require;

			// jQuery默认加载
			var $ = definition.require( 'jQuery' );
			me.__jQuery__ = $;

			// 如果App中设定了container，但是DOM树中找不到
			// 则不给App绑定事件或者执行main方法
			if ( definition.container && $( definition.container ).length == 0 ) {
				return;
			}

			// 设定Container;
			var	container = processContainer( definition, $ );

			// 绑定事件
			if ( definition.events ) {
				bindEvents( definition, $, container );
			}

			// 入口初始化
			if ( K.isFunction( definition.main ) ) {
				if ( me.execBeforeDomready ) {
					definition.main();
					ready();
				}
				// Dom Ready 后再执行
				else {
					K.ready( function() {
						definition.main();
						ready();
					} );
				}
			} else {
				ready();
			}
		} );
	}
} );

function processContainer( definition, $ ) {
	var container;
	if ( !definition.container ) {
		definition.container = document.body; // 如果没有指定container，则默认为document.body
	}

	container = $( definition.container );

	if ( !container.length || container.length > 1 ) {
		container = $( document.body );
	}

	// 修改container
	definition.container = container;
	definition.getContainer = function() {
		return container;
	};

	return container;
}

// 给APP绑定事件
var eventSpliter = /^([\w\.]+)(?:\s+(.*))?$/;
function bindEvents( app, $, container ) {
	var events = app.events;

	K.map( events, function( handler, evtStr ) {
		var match = evtStr.match( eventSpliter ),
			evtName = match[ 1 ],
			selector = match[ 2 ],
			method = K.bind( app[ handler ], app );

		if ( !selector ) {
			container.bind( evtName, method );
		}
		else {
			container.delegate( selector, evtName, K.bind( app[ handler ], app ) );
		}
	} );
}

// 生成不重复的app id
var appId = 0;
function genAppId() {
	return '__APP__' + ( appId++ );
}

function getId( info ) {
	var id = info[ 0 ];
	if ( id && K.isString( id ) ) {
		// App id 必须以A开头
		if ( K.last( id.split( /\//ig ) ).charAt( 0 ) != 'A' ) {
			throw new Error( id + ' is a invalid name for a App' );
		}
	} else {
		id = genAppId();
	}

	return id;
}

function getDepends( info ) {
	return K.detect( info, function( item ) {
		return K.isArray( item );
	} ) || [];
}

function unsafeExec( info ) {
	var execBeforeDomready = K.last( info );
	return K.isBoolean( execBeforeDomready ) ? execBeforeDomready : false;
}

/**
 * 定义APP
 * @param {string|optinal} id  App id
 * @param {array|optional} depends 依赖模块
 */
K.App = function( id, depends, execBeforeDomready ) {
	return new Application( getId( arguments ), getDepends( arguments ), unsafeExec( arguments ) );
};

K.App.get = function( appID ) {
	return appList[ appID ] || null;
};

} )( K, K.Module );

// 自定义事件
(function(K) {
	var mix = K.mix,
		indexOf = K.indexOf;

	//----------K.CustEvent----------
	/**
	 * @class CustEvent 自定义事件
	 * @namespace K
	 * @param {object} target 事件所属对象，即：是哪个对象的事件。
	 * @param {string} type 事件类型。备用。
	 * @param {object} eventArgs (Optional) 自定义事件参数
	 * @returns {CustEvent} 自定义事件
	 */
	var CustEvent = K.CustEvent = function(target, type, eventArgs) {
		this.target = target;
		this.type = type;
		mix(this, eventArgs || {});
	};

	mix(CustEvent.prototype, {
		/**
		 * @property {Object} target CustEvent的target
		 */
		target: null,
		/**
		 * @property {Object} currentTarget CustEvent的currentTarget，即事件派发者
		 */
		currentTarget: null,
		/**
		 * @property {String} type CustEvent的类型
		 */
		type: null,
		/**
		 * @property {boolean} returnValue fire方法执行后的遗留产物。(建议规则:对于onbeforexxxx事件，如果returnValue===false，则不执行该事件)。
		 */
		returnValue: undefined,
		/**
		 * 设置event的返回值为false。
		 * @method preventDefault
		 * @returns {void} 无返回值
		 */
		preventDefault: function() {
			this.returnValue = false;
		}
	});
	/**
	 * 为一个对象添加一系列事件，并添加on/un/fire三个方法，参见：K.CustEventTarget.createEvents
	 * @static
	 * @method createEvents
	 * @param {Object} obj 事件所属对象，即：是哪个对象的事件。
	 * @param {String|Array} types 事件名称。
	 * @returns {void} 无返回值
	 */

	/**
	 * @class CustEventTargetH  自定义事件Target
	 * @namespace K
	 */

	K.CustEventTargetH = {
		/**
		 * 添加监控
		 * @method on
		 * @param {string} sEvent 事件名称。
		 * @param {Function} fn 监控函数，在CustEvent fire时，this将会指向oScope，而第一个参数，将会是一个CustEvent对象。
		 * @return {boolean} 是否成功添加监控。例如：重复添加监控，会导致返回false.
		 * @throw {Error} 如果没有对事件进行初始化，则会抛错
		 */
		on: function(target, sEvent, fn) {
			var cbs = (target.__custListeners && target.__custListeners[sEvent]) || K.error("unknown event type", TypeError);
			if (indexOf(cbs, fn) > -1) {
				return false;
			}
			cbs.push(fn);
			return true;
		},
		/**
         * 添加监控(只发生一次)
         * @method once
         * @param {string} sEvent 事件名称。
         * @param {Function} fn 监控函数，在CustEvent fire时，this将会指向oScope，而第一个参数，将会是一个CustEvent对象。
         * @return {boolean} 是否成功添加监控。例如：重复添加监控，会导致返回false.
         * @throw {Error} 如果没有对事件进行初始化，则会抛错
         */
        once: function(target, sEvent, fn) {
            var cbs = (target.__custListeners && target.__custListeners[sEvent]) || K.error("unknown event type", TypeError);
            var handler = $.proxy(function(custEvent) {
                fn.call(target, custEvent);
                K.CustEventTargetH.un(target, sEvent, handler);
            }, this);

            K.CustEventTargetH.on(target, sEvent, handler);
            return true;
        },
		/**
		 * 取消监控
		 * @method un
		 * @param {string} sEvent 事件名称。
		 * @param {Function} fn 监控函数
		 * @return {boolean} 是否有效执行un.
		 * @throw {Error} 如果没有对事件进行初始化，则会抛错
		 */
		un: function(target, sEvent, fn) {
			var cbs = (target.__custListeners && target.__custListeners[sEvent]) || K.error("unknown event type", TypeError);
			if (fn) {
				var idx = indexOf(cbs, fn);
				if (idx < 0) {
					return false;
				}
				cbs.splice(idx, 1);
			} else {
				cbs.length = 0;
			}
			return true;

		},
		/**
		 * 事件触发。触发事件时，在监控函数里，this将会指向oScope，而第一个参数，将会是一个CustEvent对象，与Dom3的listener的参数类似。<br/>
		 如果this.target['on'+this.type],则也会执行该方法,与HTMLElement的独占模式的事件(如el.onclick=function(){alert(1)})类似.<br/>
		 如果createEvents的事件类型中包含"*"，则所有事件最终也会落到on("*").
		 * @method fire
		 * @param {string | sEvent} sEvent 自定义事件，或事件名称。 如果是事件名称，相当于传new CustEvent(this,sEvent,eventArgs).
		 * @param {object} eventArgs (Optional) 自定义事件参数
		 * @return {boolean} 以下两种情况返回false，其它情况下返回true.
		 1. 所有callback(包括独占模式的onxxx)执行完后，custEvent.returnValue===false
		 2. 所有callback(包括独占模式的onxxx)执行完后，custEvent.returnValue===undefined，并且独占模式的onxxx()的返回值为false.
		 */
		fire: function(target, sEvent, eventArgs) {
			if (sEvent instanceof CustEvent) {
				var custEvent = mix(sEvent, eventArgs);
				sEvent = sEvent.type;
			} else {
				custEvent = new CustEvent(target, sEvent, eventArgs);
			}

			var cbs = (target.__custListeners && target.__custListeners[sEvent]) || K.error("unknown event type", TypeError);
			if (sEvent != "*") {
				cbs = cbs.concat(target.__custListeners["*"] || []);
			}

			custEvent.returnValue = undefined; //去掉本句，会导致静态CustEvent的returnValue向后污染
			custEvent.currentTarget = target;
			var obj = custEvent.currentTarget;
			if (obj && obj['on' + custEvent.type]) {
				var retDef = obj['on' + custEvent.type].call(obj, custEvent); //对于独占模式的返回值，会弱影响event.returnValue
			}

			for (var i = 0; i < cbs.length; i++) {
				cbs[i].call(obj, custEvent);
			}
			return custEvent.returnValue !== false || (retDef === false && custEvent.returnValue === undefined);
		},
		createEvents: function(target, types) {
			/**
			 * 为一个对象添加一系列事件，并添加on/un/fire三个方法<br/>
			 * 添加的事件中自动包含一个特殊的事件类型"*"，这个事件类型没有独占模式，所有事件均会落到on("*")事件对应的处理函数中
			 * @static
			 * @method createEvents
			 * @param {Object} obj 事件所属对象，即：是哪个对象的事件。
			 * @param {String|Array} types 事件名称。
			 * @returns {any} target
			 */
			types = types || [];
			if (typeof types == "string") {
				types = types.split(",");
			}
			var listeners = target.__custListeners;
			if (!listeners) {
				listeners = target.__custListeners = {};
			}
			for (var i = 0; i < types.length; i++) {
				listeners[types[i]] = listeners[types[i]] || []; //可以重复create，而不影响之前的listerners.
			}
			listeners['*'] = listeners["*"] || [];
			return target;
		}
	};

}(K));

( function( K ) {

	var Methodized = function() {};

	var Helper = {
		/**
		 * 对helper的方法，进行methodize化，使其的第一个参数为this，或this[attr]。
		 * <strong>methodize方法会抛弃掉helper上的非function类成员以及命名以下划线开头的成员（私有成员）</strong>
		 * @method methodize
		 * @static
		 * @param {Helper} helper Helper对象，如DateH
		 * @param {optional} attr (Optional)属性
		 * @return {Object} 方法已methodize化的对象
		 */
		methodize: function(helper, attr) {
			var ret = new Methodized(); //因为 methodize 之后gsetter和rwrap的行为不一样

			for (var i in helper) {
				if (typeof helper[i] == "function" && !/^_/.test(i)) {
					ret[i] = K.methodize(helper[i], attr);
				}
			}
			return ret;
		}
	};

	K.Helper = Helper;
}( K ) );

( function( K ) {
	var mix = K.mix;

	var CustEventTarget = K.CustEventTarget = function() {
		this.__custListeners = {};
	};

	var methodized = K.Helper.methodize(K.CustEventTargetH, null, {
		on: 'operator',
		un: 'operator'
	}); //将Helper方法变成prototype方法，同时修改on/un的返回值

	mix(CustEventTarget.prototype, methodized);

	K.CustEvent.createEvents = CustEventTarget.createEvents = function(target, types) {
		K.CustEventTargetH.createEvents(target, types);
		return mix(target, CustEventTarget.prototype); //尊重对象本身的on。
	};
}( K ) );

// 存放全局性质的配置信息，例如工具生成的配置域信息等
(function(K){
	K.Env = {
		IS_LITE:	((/kx00[149]\.com/).test(location.host) || (/kaixin00[128]\.cc/).test(location.host)),
		KX_HOST:	'{_WWW_HOST_}',
		IMG_HOST:	'{_IMG_HOST_}'
	};
	K.mix( K.Env, {
		//从window.location 中获取当前域名，包含域名左边的点，如返回：.kaixin001.com
		getDomain: function(){
			var strDomain;
			strDomain	= K.Env.THIS_HOST;	// 当前域名

			var strLocation	= window.location + '';

			// 支持 kaixin001.com 、 kaixin001.cc 和 kx001.com
			var result	= strLocation.match(/:\/\/[^\/]+\.(kaixin|kx|kxjie)(00[^\/])?(\.com|\.cc)/i);

			if ( result && result[1] && result[3] ){
				strDomain	= '.' + result[1] + (result[2] || '') + result[3];
			}
			return	strDomain;
		},

		getDomainND: function(){
			return K.Env.getDomain().substr(1);
		}
	} );
} )( K );

//由于onbeforeunload事件在浏览器中只能独占，因此在添加时很容易相互覆盖，以下方法可以保留已有的方法
( function( K ) {
	K.onbeforeunload = function( callback ) {
		if( !callback ) return;
		if( typeof window.onbeforeunload == 'function' ) {
			var oldBeforeUnload = window.onbeforeunload;
			window.onbeforeunload = function() {
				//Chrome必须有返回值才会出提示，其他浏览器可以设置event参数的returnValue属性
				var v = callback.apply( null, arguments );
				var ov = oldBeforeUnload.apply( null, arguments );

				//确保所有都执行，优先返回原回调值，防止覆盖
				return ov ? ov : v;
			};
		} else {
			window.onbeforeunload = callback;
		}
	};
} )( K );

// 性能数据
( function( K ) {
	K.Performance = { timing: {} };
	var performance = window.performance || window.msPerformance || window.webkitPerformance || window.mozPerformance;
	if (performance && performance.timing) {
		K.Performance.timing = performance.timing;
	} else {
	    K.Performance.timing.responseStart = K.global.pageStart;
		K.ready(function() {
			K.Performance.timing.domContentLoadedEventStart = (new Date()).getTime();
		});
		K.load(function() {
            K.Performance.timing.loadEventStart = (new Date()).getTime();
        });
	}
} )( K );

// Default Event Handler
( function( K ) {

var getParentByTag = function(node, tagName) {
	tagName = tagName.toUpperCase();
	while (node && node.nodeName != tagName) {
		node = node.parentNode;
	}
	return node;
};

var getAttribute = function(element, attr) {
	if ('hasAttribute' in element) {
		return element.getAttribute(attr);
	} else if ('getAttributeNode' in element) {
		var node = element.getAttributeNode(attr);
		if (node) {
			return node.value;
		}
	}
	return undefined;
};

var isAppReady = function(app) {
	if (! ('App' in K) || ! K.App.get(app)) {
		K.log(app, 'not ready');
		return false;
	}
	return true;
};

var getNotReadyApp = function(element) {
	var app = getAttribute(element, 'data-app');
	if (app && app.length && !isAppReady(app)) {
		return app;
	}
	return false;
};

var delegateEvent = function(container, eventName, target) {
	var app = getNotReadyApp(container),
		ajax, href;
	if (app) {
		K.once( 'App:' + app + ':Ready', function( app ) {
			app.__jQuery__(target || container)[eventName]();
		} );
		return false;
	} else if (eventName == "click") {
		ajax = container.getAttribute('data-ajax');
		if (ajax && ajax.length) {
			href = container.getAttribute('data-ajax-url') || container.href;
			switch (ajax) {
				case 'dialog-post':
				case 'dialog':
					K.Module.createRequire().async('core/ajax/Dialog', function(Dialog) {
						Dialog.load(href, container);
					});
					break;
				case 'request-post':
				case 'request':
					K.Module.createRequire().async('core/ajax/Request', function(Request) {
						Request.load(href, container);
					});
					break;
				default:
					return;
			}
			return false;
		}
	}
	return;
};

var delegateSubmit = function(target) {
	var form = getParentByTag(target, 'FORM') || target;
	return delegateEvent(form, 'submit');
};

var delegateClick = function(target) {
	var container = getParentByTag(target, 'A') || target;
	return delegateEvent(container, 'click', target);
};

var supportSubmitBubble = (function() {
	var el = document.createElement("div");
	var support = ('onsubmit' in el);
	if (! support) {
		el.setAttribute('onsubmit', "return;");
		support = typeof el.onsubmit === 'function';
	}
	return support;
})();

var defaultEventHandler = function() {
	var document = K.global.document,
	    documentElement = document.documentElement;

	var target = null;
	documentElement.onclick = function(event) {
		event = event || window.event;
		target = event.target || event.srcElement;

		if (! supportSubmitBubble) {
			var type = target.type;
			if (type == 'submit' || type == 'image') {
				return delegateSubmit(target);
			}
		}

		var href = target.href;
		if (href && !/#$/.test(href)) {
			var isNotClick = (event.which && event.which != 1),
				isSpecialChar = (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey);

			if (isNotClick || isSpecialChar) {
				return;
			}
		}

		return delegateClick(target);
	};

	if (! supportSubmitBubble) {
		documentElement.onkeypress = function(event) {
			event = event || window.event;
			target = event.target || event.srcElement;

			var type = target.type;
			if ( (type == 'text' || type == 'password') && event.keyCode == 13) {
				return delegateSubmit(target);
			}
			return;
		};
	}

	if (supportSubmitBubble) {
		documentElement.onsubmit = function(event) {
			event = event || window.event;
			var form = event.target || event.srcElement;

			return delegateSubmit(form);
		};
	}
};

defaultEventHandler();

} )( K );

/**
 * 以下是专门为简化开发添加的插件，不属于Haibei框架（添加的插件将释放到全局）
 *
 * doT      --- 模板解析
 * Cookie   --- cookie操作
 */
(function() {

    /**
     * doT
     */
    var doT = { version : '0.1.3' };
    doT.templateSettings = {
        evaluate : /\{\{([\s\S]+?)\}\}/g,
        interpolate : /\{\{=([\s\S]+?)\}\}/g,
        encode :  /\{\{!([\s\S]+?)\}\}/g,
        defines:  /\{\{#([\s\S]+?)\}\}/g,
        varname : 'it',
        strip : true
    };
    doT.template = function(tmpl, c, defs) {
        c = c || doT.templateSettings;
        var str = ("var out='" +
                ((c.strip) ? tmpl.replace(/\s*<!\[CDATA\[\s*|\s*\]\]>\s*|[\r\n\t]|(\/\*[\s\S]*?\*\/)/g, ''):
                             tmpl)
                .replace(c.defines, function(match, code) {
                    return eval(code.replace(/[\r\t\n]/g, ' '));
                })
                .replace(/\\/g, '\\\\')
                .replace(/'/g, "\\'")
                .replace(c.interpolate, function(match, code) {
                    return "';out+=" + code.replace(/\\'/g, "'").replace(/\\\\/g,"\\").replace(/[\r\t\n]/g, ' ') + ";out+='";
                })
                .replace(c.encode, function(match, code) {
                    return "';out+=(" + code.replace(/\\'/g, "'").replace(/\\\\/g, "\\").replace(/[\r\t\n]/g, ' ') + ").toString().replace(/&(?!\\w+;)/g, '&#38;').split('<').join('&#60;').split('>').join('&#62;').split('" + '"' + "').join('&#34;').split(" + '"' + "'" + '"' + ").join('&#39;').split('/').join('&#x2F;');out+='";
                })
                .replace(c.evaluate, function(match, code) {
                    return "';" + code.replace(/\\'/g, "'").replace(/\\\\/g,"\\").replace(/[\r\t\n]/g, ' ') + "out+='";
                })
                + "';return out;")
                .replace(/\n/g, '\\n')
                .replace(/\t/g, '\\t')
                .replace(/\r/g, '\\r')
                .split("out+='';").join('')
                .split('var out="";out+=').join('var out=');

        try {
            return new Function(c.varname, str);
        } catch (e) {
            if (typeof console !== 'undefined') console.log("Could not create a template function: " + str);
            throw e;
        }
    };

    /**
     * Cookie
     */
    function Cookie(){
        return this.init.apply(this,arguments);
    }
    Cookie.prototype = (function(){
        return{
            /**
             * 初始化
             *
             * @method init
             * @public
             * @param {options}  配置
             * @return void
             */
            init:function(opt){
                opt = opt || {};
                this.path    = opt.path || "/";
                this.domain  = opt.domain || "";
                this.expires = opt.expires || 1000 * 60 * 60 * 24 * 365;
                this.secure  = opt.secure || "";
            },
            /**
             * 存储
             * @method set
             * @public
             * @param {string} key
             * @param {string} value
             * @return void
             */
            set:function(key, value){
                var now = new Date();
                if(typeof(this.expires)=="number"){
                    now.setTime(now.getTime() + this.expires);
                }
                document.cookie =
                    key + "="+ escape(value)
                    + ";expires=" + now.toGMTString()
                    + ";path="+ this.path
                    + (this.domain == "" ? "" : ("; domain=" + this.domain))
                    + (this.secure ? "; secure" : "");
            },
            /**
             * 读取
             * @method get
             * @public
             * @param {string} key
             * @return string
             */
            get:function(key){
                var a, reg = new RegExp("(^| )" + key + "=([^;]*)(;|$)");
                if(a = document.cookie.match(reg)){
                    return unescape(a[2]);
                }else{
                    return "";
                }
            },
            /**
             * 移除
             * @method remove
             * @public
             * @param {string} key
             * @return void
             */
            remove:function(key){
              var old=this.expires;
              this.expires = -1 * 1000 * 60 * 60 * 24 * 365;
              this.set(key,"");
              this.expires=old;
            }
        };
    })();


    /**
     * 存储
     * @method set
     * @static
     * @param {string} key
     * @param {string} value
     * @param {object} option
     * @return void
     */
    Cookie.set=function(key,value,option){
        var cookie = new Cookie(option);
        cookie.set(key,value);
    };

    /**
     * 读取
     * @method get
     * @static
     * @param {string} key
     * @param {object} option
     * @return string
     */
    Cookie.get=function(key,option){
        var cookie = new Cookie(option);
        var ret = cookie.get(key);
        return ret;
    };

    /**
     * 移除
     * @method set
     * @static
     * @param {string} key
     * @param {object} option
     * @return void
     */
    Cookie.remove=function(key,option){
        var cookie = new Cookie(option);
        cookie.remove(key);
    };

    // 释放到全局
    window.doT = doT;
    window.Cookie = Cookie;
}());

K.__debug = true;
